// ****************************************************************************
// CUI
//
// The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
//
// Copyright 2003-2013 The Boeing Company. All rights reserved.
//
// The use, dissemination or disclosure of data in this file is subject to
// limitation or restriction. See accompanying README and LICENSE for details.
// ****************************************************************************
// ****************************************************************************
// Updated by Infoscitex, a DCS Company.
// ****************************************************************************

#ifndef UDP_OBSERVER_HPP
#define UDP_OBSERVER_HPP

#include <string>
#include <chrono>
#include <iomanip>
#include <sstream>

// Base Class
#include "ObserverControlInterface.hpp"
#include ""

// Utilities
#include "UtCallbackHolder.hpp"

// Forward declarations listed to satisfy prototypes suggested for exercise
class  GenUDP_Connection;
class  UtInput;
struct UtPluginObjectParameters;
class  WsfPlatform;
#include "WsfScenarioExtension.hpp"
#include "WsfSimulationExtension.hpp"
#include "WsfExchange.hpp"
class  WsfSensor;
class  WsfTrack;
class  WsfMover;
class  WsfSimulation;
class Comm;
class Router;
class ProtocolInterface;
class Result;
class Address;
class Network;
class WsfMessage;
class WsfTask;
class WsfTrackId;
class WsfZone;
class WsfAdvancedBehaviorTreeNode;
class WsfAdvancedBehaviorTree;
class WsfBehaviorTreeNode;
class WsfBehaviorTree;
class WsfFuelingOperation;
class WsfFuel;
class WsfImage;
class WsfProcessor;
class WsfScriptStateMachine;
class WsfSensorMode;
class WsfSensorResult;
class WsfVisualPart;
class WsfLocalTrack;
class WsfCallback;
class WsfWeaponEngagement;
class WsfEM_Xmtr;
class WsfGuidanceComputer;
class WsfImplicitWeapon;
class WsfWeapon;
class WsfWeaponMode;
class WsfQuantumTaskerProcessor;
class WsfEM_Rcvr;
class WsfEM_Interaction;
class WsfDirectedEnergyWeapon;

enum AppearanceType;

#include "json/json.h"

//! Registers for simulation events using WsfObserver, and outputs
//! related information over a UDP socket.
class UDP_Observer : public WsfSimulationExtension
{
   public:
        //! Constructor
        UDP_Observer();
        UDP_Observer(const UDP_Observer& aSrc);
        UDP_Observer& operator=(const UDP_Observer& aSrc);
        ~UDP_Observer() noexcept override;
        bool Initialize() override;
        bool ProcessInput(UtInput& aInput);

    private:
		struct PlatformSideInfo
		{
			int index;
			std::string side;
			PlatformSideInfo(int idx, const std::string& s) : index(idx), side(s) {}
		};

		struct InterfaceError
		{
			int errorCode;
			std::string errorInfo;
			InterfaceError(int errorCode, const std::string& info) : errorCode(errorCode), errorInfo(info) {}
		};

    public:
        //处理外部来的消息
        InterfaceError DecodeMsg(std::string msg);
        InterfaceError HandleMsg_Start(Json::Value& data);
        InterfaceError HandleMsg_Pause(Json::Value& data);
		InterfaceError HandleMsg_Resume(Json::Value& data);
		InterfaceError HandleMsg_Complete(Json::Value& data);
		
        //移动
        InterfaceError HandleMsg_LocationChange(Json::Value& data);
        InterfaceError HandleMsg_MoveTo(Json::Value& data);
		InterfaceError HandleMsg_Speed(Json::Value& data);

        //仿真
		InterfaceError HandleMsg_SimClockRate(Json::Value& data);
        InterfaceError HandleMsg_SimAdvanceTime(Json::Value& data);

        //组件
        InterfaceError HandleMsg_AttackTarget(Json::Value& data);
		InterfaceError HandleMsg_ControlSensor(Json::Value& data);

    private:
        int                  mPort; //发送到目标端口
        int                  mRecvPort;//接收数据的本地地址
        std::string          mAddress;//发送数据到目标IP地址
        std::vector<PlatformSideInfo> mPlatformSides = {};  // 存储所有平台信息

        UtCallbackHolder     mCallbacks;
        GenUDP_Connection*   mConnectionPtr;
		void Disconnect();
        void initPlatformSides();

        // WsfMoverObserver
        void MoverUpdated(double aSimTime, WsfMover* aMover);

        // WsfPlatformObserver
        void PlatformAdded(double aSimTime, WsfPlatform* aPlatform);
        void PlatformDeleted(double aSimTime, WsfPlatform* aPlatform);

        // WsfSensorObserver
        void SensorDetectionAttempt(double aSimTime, WsfSensor* aSensor, WsfPlatform* aPlatform, WsfSensorResult& aResult);
        void SensorDetectionChanged(double aSimTime, WsfSensor* aSensor, size_t aDetectionIndex, WsfSensorResult& aResult);
        void SensorOperational(double aSimTime, WsfSensor* aSensor);
        void SensorRequestCanceled(double aSimTime, WsfSensor* aSensor, const WsfTrack* aTrack);
        void SensorRequestInitiated(double aSimTime, WsfSensor* aSensor, WsfSensorMode* aMode, const WsfTrack* aTrack);
        void SensorRequestUpdated(double aSimTime, WsfSensor* aSensor, WsfSensorMode* aMode, const WsfTrack* aTrack);
        void SensorScanUpdated(double aSimTime, WsfSensor* aSensor);

        // WsfSimulationObserver
        void AdvanceTime(double aSimTime);
        void RequestTimeAdvance(double aSimTime, double aRequestedTime, double aGrantedTime);
        void SimulationClockRateChange(double aSimTime);
        void SimulationInitializing();
        void SimulationStarting();
        void SimulationPausing();
        void SimulationResuming();
        void SimulationComplete(double aSimTime);

        // WsfTrackObserver
        void LocalTrackDropped(double aSimTime, WsfPlatform* aPlatform, const WsfLocalTrack* aTrack);
        void LocalTrackInitiated(double aSimTime, WsfPlatform* aPlatform, const WsfLocalTrack* aLocalTrack, const WsfTrack* aSensorTrack);
        void LocalTrackUpdated(double aSimTime, WsfPlatform* aPlatform, const WsfLocalTrack* aLocalTrack, const WsfTrack* aSensorTrack);
        void SensorTrackCoasted(double aSimTime, WsfSensor* aSensor, const WsfTrack* aTrack);
        void SensorTrackDropped(double aSimTime, WsfSensor* aSensor, const WsfTrack* aTrack);
        void SensorTrackInitiated(double aSimTime, WsfSensor* aSensor, const WsfTrack* aTrack);
        void SensorTrackUpdated(double aSimTime, WsfSensor* aSensor, const WsfTrack* aTrack);

		// WsfWeaponObserve
		void WeaponFireAborted(double aSimTime, WsfWeapon* aWeapon, const WsfTrack* aTrack, double aTime);
		void WeaponFired(double aSimTime, const WsfWeaponEngagement* aEngagement, const WsfTrack* aTrack);
		void WeaponFireRequested(double aSimTime, WsfWeapon* aWeapon, const WsfTrack* aTrack, double aTime);
		void WeaponPlatformPendingAdd(double aSimTime, WsfPlatform* aPlatform, const WsfWeaponEngagement* aEngagement, const WsfTrack* aTrack);
		void WeaponHit(double aSimTime, const WsfWeaponEngagement* aEngagement, WsfPlatform* aTarget);
		void WeaponKilled(double aSimTime, WsfWeapon* aWeapon);
		void WeaponMissed(double aSimTime, const WsfWeaponEngagement* aEngagement, WsfPlatform* aTarget);

        //辅助函数
        Json::Value GenerateSimulationData(double aSimTime);
		static std::string ConvertTimeToISOString(double simTime);
        Json::Value CreateCombatUnit(WsfPlatform* platform);
        void SendPacket(const std::string& aMessage);
};

#endif
